package cn.com.bluemoon.daps.standard.excel.easypoi;

import cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult;
import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
import cn.com.bluemoon.daps.standard.vo.BasicStandardAndDicMiddleVo;
import cn.com.bluemoon.daps.standard.excel.BaseCacheVerifyHandler;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.map.CaseInsensitiveMap;
import reactor.util.function.Tuples;

import java.io.Closeable;
import java.util.*;

/**
 * @author Jarod.Kong
 * @date 2020/8/26 17:27
 */
public class BsAndDicMidVerifyHandler extends BaseCacheVerifyHandler
        implements IExcelVerifyHandler<BasicStandardAndDicMiddleVo>, Closeable {
    /**
     * *代码名称 => *中文名称+备注	 缓存
     */
    private static final Map<String, Object> CACHE_CODE_AND_CODE_NAME_MAP = new CaseInsensitiveMap<>();
    /**
     * 数据库中的已发布的标准中英文db
     */
    private Set<String> dbPublishedStandardNames = Sets.newHashSet();
    private Set<String> dbPublishedStandardCodeNames = Sets.newHashSet();
    /**
     * 有序的中文名称
     */
    static List<String> hadReadStandardNames = Lists.newArrayList();
    /**
     * 有序的代码名称
     */
    static List<String> hadReadStandardCodeNames = Lists.newArrayList();

    public BsAndDicMidVerifyHandler() {
        // nothing
    }

    /**
     * 导入校验方法
     *
     * @param obj 对象
     * @return
     */
    @Override
    public ExcelVerifyHandlerResult verifyHandler(BasicStandardAndDicMiddleVo obj) {
        int currentRowIndex = sheetRowIndex.incrementAndGet();
        if (obj != null) {
            // 针对标准中文名称校验
            String uniqueKey = obj.getName();
            int rowIndex = hadReadStandardNames.indexOf(uniqueKey);
            hadReadStandardNames.add(uniqueKey);
            List<String> errorMsgs = Lists.newArrayList();
            String errorMsg = null;
            if (rowIndex >= 0) {
                errorMsg = String.format("第%d行与前第%d行的[中文名称]列值一样", currentRowIndex, rowIndex + 2);
                errorMsgs.add(errorMsg);
            }
            if (dbPublishedStandardNames.contains(obj.getName())) {
                errorMsg = String.format("第%d行的[中文名称]列值，系统标准中已存在", currentRowIndex);
                errorMsgs.add(errorMsg);
            }
            // 针对标准英文名称校验
            uniqueKey = obj.getBaseCodeName();
            rowIndex = hadReadStandardCodeNames.indexOf(uniqueKey);
            hadReadStandardCodeNames.add(uniqueKey);
            if (rowIndex >= 0) {
                errorMsg = String.format("第%d行与前第%d行的[代码名称]列值一样", currentRowIndex, rowIndex + 2);
                errorMsgs.add(errorMsg);
            }
            if (dbPublishedStandardCodeNames.contains(uniqueKey)) {
                errorMsg = String.format("第%d行的[代码名称]列值，系统标准中已存在", currentRowIndex);
                errorMsgs.add(errorMsg);
            }
            CACHE_CODE_AND_CODE_NAME_MAP.put(obj.getBaseCodeName(), Tuples.of(Objects.toString(obj.getName(), ""), Objects.toString(obj.getBaseRemark(),"" )));
            if (!errorMsgs.isEmpty()) {
                return new ExcelVerifyHandlerResult(false, String.join("；", errorMsgs));
            }
        }
        return new ExcelVerifyHandlerResult(true);
    }

    @Override
    public void close() {
        dbPublishedStandardCodeNames.clear();
        dbPublishedStandardNames.clear();
        hadReadStandardCodeNames.clear();
        hadReadStandardNames.clear();
    }

    public void setDbPublishedStandardCodeNames(Set<String> dbPublishedStandardCodeNames) {
        this.dbPublishedStandardCodeNames = dbPublishedStandardCodeNames;
    }

    public void setDbPublishedStandardNames(Set<String> dbPublishedStandardNames) {
        this.dbPublishedStandardNames = dbPublishedStandardNames;
    }

    public BsAndDicMidVerifyHandler setDbPublishedStandardCodeAndName(Map<String, String> stdDicCodeAndName) {
        if (stdDicCodeAndName != null) {
            this.dbPublishedStandardCodeNames = stdDicCodeAndName.keySet();
            this.dbPublishedStandardNames = new HashSet<>(stdDicCodeAndName.values());
        }
        return this;
    }


    @Override
    public Map<String, Object> getSheetCacheMap() {
        return CACHE_CODE_AND_CODE_NAME_MAP;
    }
}